/*************************************************
* Title： TinyToolKit
* Author：Opportunity 
* Discribe：双向链表的封装类
* CreateTime：2020-04-04 16:56:48
* Version：1.0
* Modify Recoder：
*************************************************/

using System.Collections.Generic;

namespace TinyToolKit
{
    public class CMapList<T> where T : class, new()
    {
        DoubleLinkedList<T> _Dlink = new DoubleLinkedList<T>();
        Dictionary<T, DoubleLinkedListNode<T>> _findMap = new Dictionary<T, DoubleLinkedListNode<T>>();

        ~CMapList()
        {
            Clear();
        }

        /// <summary>
        /// 插入节点到表头，并保存节点在字典中
        /// </summary>
        /// <param name="t"></param>
        public void InsertToFirst(T t)
        {
            DoubleLinkedListNode<T> node = null;
            if (_findMap.TryGetValue(t, out node) && node != null)
            {
                //_Dlink.AddFirst(node);
                return;
            }

            _Dlink.AddFirst(t);
            _findMap.Add(t, _Dlink.Head);
        }

        /// <summary>
        /// 删除尾部节点
        /// </summary>
        public void Pop()
        {
            if (_Dlink.Tail != null)
            {
                Remove(_Dlink.Tail.t);
            }
        }

        /// <summary>
        /// 删除某个节点
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool Remove(T t)
        {
            DoubleLinkedListNode<T> node = null;
            if (_findMap.TryGetValue(t, out node) == false || node == null)
            {
                return false;
            }

            _Dlink.Remove(node);
            _findMap.Remove(t);
            return true;
        }

        /// <summary>
        /// 获取尾部节点的类型
        /// </summary>
        public T GetLast()
        {
            return _Dlink.Tail?.t;
        }

        /// <summary>
        /// 返回节点个数
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return _findMap.Count;
        }

        public bool Contains(T t)
        {
            DoubleLinkedListNode<T> node = null;
            if (_findMap.TryGetValue(t, out node) == false || node == null)
                return false;
            return true;
        }

        /// <summary>
        /// 将节点移动到头部
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool MoveToFirst(T t)
        {
            DoubleLinkedListNode<T> node = null;
            if (_findMap.TryGetValue(t, out node) == false || node == null)
                return false;

            _Dlink.MoveToFirst(node);
            return true;
        }

        public void Clear()
        {
            while (_Dlink.Tail != null)
            {
                Remove(_Dlink.Tail.t);
            }
        }
    }
}